package com.imflea.zero.filter;


import com.imflea.zero.constant.QxContant;
import com.imflea.zero.util.ZeroCacheUtils;
import com.imflea.zero.util.ZeroJsonUtils;
import com.imflea.zero.util.base.CommonUtils;
import com.imflea.zero.util.base.JsonResult;
import com.imflea.zero.util.base.ZeroThreadLocalUtils;
import com.imflea.zero.utils.SessionUtils;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

;

/**
 * @author 祥保玉
 * @PackageName: com.imflea.zero.filter
 * @ClassName: WxSessionFilter
 * @Description
 * @date 2021-09-13  14:58:31
 */
@Slf4j
public class WxSessionFilter implements Filter {
    private String ignorePattern;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.ignorePattern = filterConfig.getInitParameter("ignorePattern");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        Map<String, String> headersInfo = CommonUtils.getHeadersInfo(request);
        String tenantId = headersInfo.get("tenantid");
        //api部分除外，如：支付回调接口中，无法传递tenantId参数信息
//        if (CommonUtils.isNull(tenantId)) {
//            //返回401,请求登录
//            JsonResult<Map<String, Object>> result = new JsonResult<>();
//            result.setCode("401");
//            response.setStatus(401);
//            response.getWriter().write(result.toJsonString());
//            return;
//        }
        ZeroThreadLocalUtils.add("tenantId", tenantId);
        if (isRequestUrlExcluded(request)) {
            filterChain.doFilter(request, response);
            return;
        } else {
            String accessToken = headersInfo.get(QxContant.getWxLoginAccessTokenKey4front().toLowerCase());
            try {
                if (CommonUtils.isNull(accessToken) || CommonUtils.isNull(tenantId)) {
                    //返回401,请求登录
                    JsonResult<Map<String, Object>> result = new JsonResult<>();
                    result.setCode("401");
                    response.setStatus(401);
                    response.getWriter().write(ZeroJsonUtils.entityToJson(result));
                    return;
                }
                String cacheTokenMap = ZeroCacheUtils.getString(QxContant.getWxLoginAccessTokenKey() + tenantId + ":" + accessToken);
//                String cacheTokenMap =ZeroCacheUtils.getString(token);

                if (CommonUtils.isNull(cacheTokenMap)) {
                    //返回401,请求登录
                    JsonResult<Map<String, Object>> result = new JsonResult<>();
                    result.setCode("401");
                    response.setStatus(401);
                    response.getWriter().write(ZeroJsonUtils.entityToJson(result));
                    return;
                }
                Map<String, Object> tokenInfo = ZeroJsonUtils.jsonToMap(cacheTokenMap);
                if (CommonUtils.isNull(tokenInfo)) {
                    //返回401,请求登录
                    JsonResult<Map<String, Object>> result = new JsonResult<>();
                    result.setCode("401");
                    response.getWriter().write(ZeroJsonUtils.entityToJson(result));
                    return;
                } else {
                    //AegisCacheUtils.expire(accessToken, QxContant.getSessionTime());永不过期
                    //此处应该从换从中获取登录认证信息，校验是否有效
                    SessionUtils.makeWxSession(tokenInfo, request);
                    increaseAccessUser(tenantId);
                    filterChain.doFilter(request, response);
                }
            } catch (Exception e) {
                e.printStackTrace();
                //返回401,请求登录
                e.printStackTrace();
                response.setStatus(500);
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().append("业务异常,请联系管理员！");
                return;
            }
        }

    }

    @Override
    public void destroy() {
        ZeroThreadLocalUtils.clear();

    }

    /**
     * @param tenantId
     * @return boolean
     * @author 祥保玉
     * @description 用来统计每天访问人数
     * @date 2022/1/13  14:13
     */


    private boolean increaseAccessUser(String tenantId) {
        try {
            ZeroCacheUtils.setString(QxContant.getWxAccessUserNumPrefix() + tenantId + ":" + SessionUtils.getUserId(), SessionUtils.getUserId());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    private boolean isRequestUrlExcluded(HttpServletRequest request) {
        StringBuffer urlBuffer = request.getRequestURL();
        if (request.getQueryString() != null) {
            urlBuffer.append("?").append(request.getQueryString());
        }
        String requestUri = urlBuffer.toString();
        String pattern = ".*(swaggerCheck|swagger-ui|swagger-resources|webjars|springfox|api-docs|v4|csrf).*";

        return (requestUri.matches(this.ignorePattern) || requestUri.matches(pattern));
    }
}
